//----------------------------------------------------------------------------
// soldier.cs - soldier datablocks and aiplayer methods that apply to soldier
//----------------------------------------------------------------------------
datablock PlayerData(EnemyPatrol : PlayerBody)
{
	className = Armor;
	shapeFile = "~/data/shapes/player/player.dts";
	maxDamage = 40;
	maxInv[RocketPistol] = 1;
	maxInv[RocketPistolAmmo] = 99999;
};

// %obj is an instance of an AIPlayer which uses the EnemyPatrol class
function EnemyPatrol::init(%this, %obj)
{
	%obj.setSkinName("jinroh");
	%obj.setInventory(RocketPistol,1);
	%obj.mountImage(RocketPistolImage, 0);
	%obj.setInventory(RocketPistolAmmo,9999);
	// If it has a path; start it up
	if (%obj.path !$= "")
	{
		%obj.followPath(%obj.path,1);
		%obj.moveToNextNode();
	}
}

/*
function EnemyPatrol::spawn(%this, %path)
{
	echo("Spawning EnemyPatrol");
	
	%me = new AIPlayer() {
		dataBlock = EnemyPatrol;
		aiPlayer = true;
	};
	MissionCleanup.add(%me);

	%me.setSkinName("jinroh");
}*/

/*
function EnemyPatrol::spawnOnPath(%name,%path,%datablockType,%transf){
  // Spawn a player and place him on the first node of the path, and start him running
  if(%path $= ""){
    %player = AIPlayer::spawn(%name,%transf,%datablockType);
    %player.Ssetup();
    %player.stoppath();
    %player.futureSchedule = %player.Sthink();
  }else{
    %node = %path.getObject(0);
    %player = AIPlayer::spawn(%name,%node.getTransform(),%datablockType);
    %player.Ssetup();
    %player.path = %path;
    %player.currentNode = 0;
    %player.targetNode = %player.path.getCount() - 1;
    %player.futureSchedule = %player.Sthink();
    %player.moveToNextNode();
  }
  return %player;
}
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// normal methods
//-----------------------------------------------------------------------------
function AIPlayer::Ssetup(%this){
  %this.HeardAlertLevel = 10;
  %this.SeenAlertLevel = 20;
  %this.AlertLevel = 0;
  %this.Sstate = "Patrol";
  %this.Sfrozen = 0;
  %this.SfrozenThreshold = 0;
  %this.mountImage(PistolImage,0);
  %this.setImageAmmo(0,true);
}
//-----------------------------------------------------------------------------
function AIPlayer::Sthink(%this){
   //Stop thinking if we are dead
   if (%this.getState() $= "Dead")
    return;

   // Handle being frozen by neutralizer
   if(%this.Sstate $= "Frozen"){
      if(%this.Sfrozen++ > 12)
        %this.Sunfreeze();
   }else{
     // More relaxed on Patrol 
     if(%this.Sstate $= "Patrol"){
       %this.hearDistance = 10;
       %this.seeDistance = 20;
     }else{
       %this.hearDistance = 20;
       %this.seeDistance = 35;
     }

     %ourloc = %this.getPosition();
      
     // Don't bother thinking if the player isn't on the map      
     if(ClientGroup.getCount()<1)
       %client = -1;
     else
       %client = ClientGroup.getObject(0);
     if (%client != -1) {
	    if (!(%client.player $= "" || %client.player == 0))
		 {
         %playerloc = %client.player.getPosition();

         // Look if the AI can hear you
         if(VectorDist(%ourloc, %playerloc) < %this.hearDistance){
           %this.aimAtStandingObject(%client.player);
           %this.Sstate = "Heard";
         }
         
         // Check first if the player is close enough
         if (VectorDist(%ourloc, %playerloc) < %this.seeDistance){
           // Check FOV
           %eyeVec = VectorNormalize(%this.getEyeVector());
           %between = VectorNormalize(VectorSub(%playerloc, %ourloc));
           if(VectorDist(%eyeVec,%between)<1.0){
             // Check obstructions
             %mask = $TypeMasks::TerrainObjectType | $TypeMasks::StaticObjectType | $TypeMasks::StaticShapeObjectType | $TypeMasks::InteriorObjectType;
             // Make sure we cast near eye level
             %ray = ContainerRayCast(VectorAdd(%ourloc,"0.0 0.0 1.0"), VectorAdd(%playerloc,"0.0 0.0 1.0"), %mask);

             //If theres nothing in the way, we can see the player
             if (!%ray){
               %this.aimAtStandingObject(%client.player);
               %this.Sstate = "Seen";
             }
           }
			}
        
        if(%this.Sstate $= "Alert"){
          // Nothing seen or heard, relax a bit
          %this.AlertLevel--;

          // Start running after a while (if we can)
          if((%this.AlertLevel == 5) && (%this.currentNode != -1))
            %this.moveToNode(%this.currentNode);
          
          // All clear
          if(%this.AlertLevel <= 0){
            %this.clearAim();
            %this.Sstate = "Patrol"; 
          }
        }
        
        if(%this.Sstate $= "Heard"){
          // Stop moving
          %this.stop();
          // Announce if we aren't very alert coming in
          if(%this.AlertLevel<(%this.HeardAlertLevel/2.0))
            %this.Salertneighbors(%client.player,%this.HeardAlertLevel);
          // Be Alert
          %this.AlertLevel=%this.HeardAlertLevel;
          %this.Sstate = "Alert";
        }
        
        if(%this.Sstate $= "Seen"){
          // Stop moving
          %this.stop();
          // Fire
          %this.setImageTrigger(0,true);
          %this.setImageTrigger(0,false);
          // Announce if we aren't very alert coming in
          if(%this.AlertLevel<(%this.SeenAlertLevel/2.0))
            %this.Salertneighbors(%client.player,%this.SeenAlertLevel);
          // Be Alert
          %this.AlertLevel=%this.SeenAlertLevel;
          %this.Sstate = "Alert";
        }
          
//        if(%this.Sstate $= "Patrol") - We could do more during patrol
   	 }
		}
   }
   %this.futureSchedule = %this.schedule(500-(%this.AlertLevel*10),Sthink);
}
//-----------------------------------------------------------------------------
function EnemyPatrol::onReachDestination(%this, %obj){
  // Moves to the next node on the path.
  // a specific player datablock or class of players.
  if (%obj.path !$= "") {
    if (%obj.currentNode == %obj.targetNode){
      %this.onEndOfPath(%obj,%obj.path);
    }else
      %obj.moveToNextNode();
  }else{
    %obj.nextTask();  
  }
}
//-----------------------------------------------------------------------------
function EnemyPatrol::onEndOfPath(%this,%obj,%path){
  // Head back the other way
  if(%obj.currentNode == 0)
    %obj.targetNode = %obj.path.getCount() - 1;
  else
    %obj.targetNode = 0;  
  
  // Turn around and run back
  %obj.clearTasks();
  %obj.pushTask("wait(10)");
  %obj.pushTask("moveToNextNode()");
  %obj.nextTask();
}

//-----------------------------------------------------------------------------
function EnemyPatrol::onEndSequence(%this,%obj,%slot){
  %obj.stopThread(%slot);
  %obj.nextTask();
}

//-----------------------------------------------------------------------------
function AIPlayer::damage(%this, %sourceObject, %position, %damage, %damageType){
  if(%damageType $= "WaterProjectile"){
    // Accumulate until frozen
    if(%this.SfrozenThreshold++ > 8) {
      %this.Sfreeze();
      %this.SfrozenThreshold=0;
    }
  }else if(%damageType $= "MindProjectile"){
    %this.mindpush();  
  }else
    %this.applyDamage( %damage );
}
//-----------------------------------------------------------------------------
function AIPlayer::Sfreeze(%this){
  %this.stop();
  %this.Sfrozen = 0;
  %this.Sstate = "Frozen";
  %this.animate("scoutroot");
}
//-----------------------------------------------------------------------------
function AIPlayer::Sunfreeze(%this){
  %this.animate("head");
  %this.Sfrozen = 0;
  %this.Sstate = "Patrol";
  if(%this.currentNode != -1)
    %this.moveToNode(%this.currentNode);
}
//-----------------------------------------------------------------------------
function AIPlayer::mindpush(%this){
  // Stop and eliminate path as we don't know where we'll be
  %this.stoppath();
  // Throw the AI
  %client = ClientGroup.getObject(0);
  %tothrow = "0 0 1";               //Shouldn't need this unless player dies and throwing
   if (%client != -1)
		if (!(%client.player $= "" || %client.player == 0))
		{
        %playerloc = %client.player.getPosition();
        %between = VectorSub(%this.getPosition(), %playerloc);
        %norm = VectorNormalize(%between);
        %tothrow = VectorScale(VectorAdd(%norm,"0 0 2"),500);
//        echo("Normalized Vector: " @ %norm @ "  " @ "Tothrow Vector: " @ %tothrow);
		}
  // Reset Velocity so they can't do a double throw
  %this.setVelocity("0 0 0");
  // Mindpush them
  %this.applyImpulse(%this.getPosition(),%tothrow);
  // Give an animation
  %this.animate("death11");
  // Go back to patrol
  %this.Sstate = "Patrol";
}
//-----------------------------------------------------------------------------
function AIPlayer::stoppath(%this){
  %this.stop();
  %this.path = "";
  %this.currentNode = -1;
  %this.targetNode = -1;
}
//-----------------------------------------------------------------------------
function AIPlayer::aimAtStandingObject(%this,%object){
  %this.setAimObject(%object);
  %this.setAimLocation(VectorAdd(%object.getPosition(),"0 0 1")); // Finney bug fix + MAH Bug Fix
}
//-----------------------------------------------------------------------------
function AIPlayer::Salertneighbors(%this,%player,%level){
  %aiseen = 0;
  %radius = 30.0;
  InitContainerRadiusSearch(%this.getPosition(), %radius, $TypeMasks::PlayerObjectType);
  while ((%targetObject = containerSearchNext()) != 0)
  	 if(%targetobject.getclassname() $= "AIPlayer")
  	   if ((%targetobject.getDataBlock().getName() $= "SoldierPrivate") && (%targetobject!=%this)){
  		  %targetobject.schedule(10,Salertme,%player,%level);
		  %aiseen++;
		}
  if(%aiseen > 0)
    %this.playAudio(0,AIHeyThereSound);
}
//-----------------------------------------------------------------------------
function AIPlayer::Salertme(%this,%player,%level){
   %this.aimAtStandingObject(%player);
   %this.AlertLevel=%level;
   %this.Sstate = "Alert";
}
//-----------------------------------------------------------------------------
*/